package main

import (
	"context"
	"fmt"
	"serial/mySerial"
	"serial/utils"
	"time"

	"github.com/wailsapp/wails/v2/pkg/runtime"
	"go.bug.st/serial"
)

// App struct
type App struct {
	ctx context.Context
}

// NewApp creates a new App application struct
func NewApp() *App {
	return &App{}
}

// startup is called when the app starts. The context is saved
// so we can call the runtime methods
func (a *App) startup(ctx context.Context) {
	a.ctx = ctx
}

// Greet returns a greeting for the given name
func (a *App) Greet(name string) string {
	return fmt.Sprintf("Hello %s, It's show time!", name)
}

// 获取到串口列表
func (a *App) GetPortsListApi() string {
	coms := mySerial.SerialList()
	return utils.SuccessRes(coms, "串口打开成功")
}

// 打开串口
func (a *App) OpenPortsApi(com string) string {
	// 配置串口
	mode := &serial.Mode{
		BaudRate: 9600,
		Parity:   serial.NoParity,
		DataBits: 8,
		StopBits: serial.OneStopBit,
	}

	// 打开串口
	Port, PortErr = serial.Open("COM3", mode)
	if PortErr != nil {
		return utils.FailRes(nil, "串口打开失败")
	}
	return utils.SuccessRes(nil, "串口打开成功")
}

// 发送串口数据
func (a *App) SendPortApi(name string) string {
	if Port == nil {
		return utils.FailRes(nil, "串口没有打开")
	}
	data, dataErr := mySerial.HexStringToBytesWithCRC(name)
	if dataErr != nil {
		return utils.FailRes(nil, "报文错误 必须是16进制的 且空格")
	}
	SendN, SendErr := mySerial.SerialSend(Port, data)
	if SendErr != nil {
		return utils.FailRes(nil, "发送串口数据错误")
	}
	return utils.SuccessRes(SendN, "发送数据成功")
}

// 扫描设备
func (a *App) ScanDeviceApi(com string) string {
	fmt.Println("开始扫描设备", com)
	// com := coms[0]

	// 配置串口
	mode := &serial.Mode{
		BaudRate: 4800,
		Parity:   serial.NoParity,
		DataBits: 8,
		StopBits: serial.OneStopBit,
	}

	// 打开串口
	Port, PortErr := serial.Open(com, mode)

	if PortErr != nil {
		return utils.FailRes(nil, "错误 打开串口失败 请检查 是否被占用")
		// return false
	}
	defer Port.Close()
	Port.SetReadTimeout(time.Duration(80) * time.Millisecond)

	// 4800,
	bauds := [8]int{9600, 14400, 19200, 28800, 38400, 57600, 115200}
	// bauds := [2]int{4800, 9600}

	for _, baud := range bauds {
		tempStart := time.Now().Unix() // 记录开始时间
		fmt.Println("baud", baud, com)
		mode.BaudRate = baud
		Port.SetMode(mode)
		// 发送事件跳转到数据页面并携带数据
		runtime.EventsEmit(a.ctx, "msg", fmt.Sprintf("开始波特率：%d 搜索...", baud))
		// 具体地址位 采取轮询
		var addr uint8 = 0x01
		for i := 0; i < 50; i++ {
			sendData := []byte{addr, 0x03, 0x00, 0x00, 0x00, 0x01}
			realData := mySerial.AddSendCrc(sendData)
			// realData := []byte{0x01, 0x03, 0x00, 0x00, 0x00, 0x02,0xC4,0x0B}
			fmt.Printf("\t addr : %d realData: % X \n", addr, realData)

			scanFlag, readBuff := mySerial.PortSendRead(Port, realData)
			// fmt.Printf("\t scanFlag %s \n", scanFlag)
			if scanFlag {
				fmt.Printf("\t 波特率 %d 地址位：%d \n", baud, addr)
				type DeviceInfo struct {
					Addr int    `json:"addr"`
					Baud int    `json:"baud"`
					Send string `json:"send"`
					Read string `json:"read"`
				}

				return utils.SuccessRes(DeviceInfo{
					Addr: int(addr),
					Baud: baud,
					Send: fmt.Sprintf("% X", realData),
					Read: fmt.Sprintf("% X", readBuff),
				}, "查询成功")
				// break
			}
			addr++
		}

		tempEnd := time.Now().Unix() // 记录开始时间
		runtime.EventsEmit(a.ctx, "msg", fmt.Sprintf("结束波特率：%d 搜索,用时：%d", baud, tempEnd-tempStart))
		fmt.Printf("所用时间：%d 秒 \n", tempEnd-tempStart)
		// break
	}
	return utils.FailRes(nil, "未找到设备，请检查线是否接好 串口选择对了吗")
}
